package main

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"html/template"
	"log"
	"net/http"
)

type User struct {
	ID       int
	Name     string
	Password string
}

func hello(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"name": "lbd",
	})
}

//调用不转义模板
func buZhuanYi() {
	r := gin.Default()

	r.SetFuncMap(template.FuncMap{
		"safe": func(str string) template.HTML {
			return template.HTML(str)
		},
	})
	//r.Static("/static", "./static")    //加载静态文件
	r.LoadHTMLGlob("biz/template/*")
	r.GET("index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "buzhuanyi.html", "<a href='https://liwenzhou.com'>李文周的博客</a>")
	})
	r.Run("localhost:9090")
}
func firstDemo() {
	r := gin.Default()
	r.LoadHTMLGlob("biz/template/*")
	r.GET("/hello", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"hello": "world",
		})
	})
	r.GET("/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", gin.H{
			"title": "11111111",
		})
	})
	r.GET("/users/index", func(c *gin.Context) {
		fmt.Println("开始")
		c.HTML(http.StatusOK, "users.html", gin.H{
			"title": "users/index",
		})
	})

	r.Run("localhost:9090")
}

//返回结构体数据的json格式
func manyJson() {
	r := gin.Default()
	u := User{
		ID:       1,
		Name:     "dsdsd",
		Password: "dssfsffs",
	}
	r.GET("/json", func(context *gin.Context) {

		context.JSON(http.StatusOK, u)
	})
	r.Run(":9090")
}

//获取get请求参数
func getParam() {
	//Default返回一个默认的路由引擎
	r := gin.Default()
	r.GET("/user/search", func(c *gin.Context) {
		username := c.DefaultQuery("username", "小王子") //没有给的默认值
		//username := c.Query("username")
		address := c.Query("address")
		//输出json结果给调用方
		c.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": username,
			"address":  address,
		})
	})
	r.Run(":9090")
}

//获取post提交
type User1 struct {
	Username string `form:"username" json:"username" binding:"required"`
	Address  string `form:"address" json:"password" binding:"required"`
}

func getPost() {
	//Default返回一个默认的路由引擎
	r := gin.Default()
	r.POST("/user/search", func(c *gin.Context) {
		// DefaultPostForm取不到值时会返回指定的默认值
		//username := c.DefaultPostForm("username", "小王子")
		//username := c.PostForm("username")
		//address,ok := c.GetPostForm("address")
		//if !ok {
		//	address = "***"
		//}
		var user User1
		c.ShouldBind(&user) //绑定参数
		//输出json结果给调用方
		c.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": user.Username,
			"address":  user.Address,
		})
	})
	r.Run(":9090")

}
func getJsonQuery() {
	r := gin.Default()
	r.POST("/json", func(c *gin.Context) {
		// 注意：下面为了举例子方便，暂时忽略了错误处理
		b, _ := c.GetRawData() // 从c.Request.Body读取请求数据
		// 定义map或结构体
		var m map[string]interface{}
		// 反序列化
		_ = json.Unmarshal(b, &m)

		c.JSON(http.StatusOK, m)
	})
	r.Run(":9090")
}

//请求的参数通过URL路径传递，例如：/user/search/小王子/沙河。 获取请求URL路径中的参数的方式如下。
func pathQuery() {
	//Default返回一个默认的路由引擎
	r := gin.Default()
	r.GET("/user/search/:username/:address", func(c *gin.Context) {
		username := c.Param("username")
		address := c.Param("address")
		//输出json结果给调用方
		c.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": username,
			"address":  address,
		})
	})

	r.Run(":9090")
}

//上传文件
func uploadfile() {
	router := gin.Default()
	// 处理multipart forms提交文件时默认的内存限制是32 MiB
	// 可以通过下面的方式修改
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	router.LoadHTMLGlob("biz/template/uploadfile.html")
	router.GET("/upload", func(c *gin.Context) {
		c.HTML(http.StatusOK, "uploadfile.html", gin.H{})
	})
	router.POST("/upload", func(c *gin.Context) {
		// 单个文件
		file, err := c.FormFile("f1")
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"message": err.Error(),
			})
			return
		}
		log.Println(file.Filename)
		dst := fmt.Sprintf("C:\\git\\%s", file.Filename)
		// 上传文件到指定的目录
		fmt.Println(dst)
		c.SaveUploadedFile(file, dst)
		c.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("'%s' uploaded!", file.Filename),
		})
	})
	router.Run(":9090")
}
func manyuploadfile() {
	router := gin.Default()
	// 处理multipart forms提交文件时默认的内存限制是32 MiB
	// 可以通过下面的方式修改
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	router.POST("/upload", func(c *gin.Context) {
		// Multipart form
		form, _ := c.MultipartForm()
		files := form.File["file"]

		for index, file := range files {
			log.Println(file.Filename)
			dst := fmt.Sprintf("C:/tmp/%s_%d", file.Filename, index)
			// 上传文件到指定的目录
			c.SaveUploadedFile(file, dst)
		}
		c.JSON(http.StatusOK, gin.H{
			"message": fmt.Sprintf("%d files uploaded!", len(files)),
		})
	})
	router.Run()
}

//http重定向
func chongdingxiang() {
	r := gin.Default()
	r.GET("/test", func(c *gin.Context) {
		c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com/")
	})
	//路由重定向,本项目内跳转
	r.GET("/test", func(c *gin.Context) {
		// 指定重定向的URL
		c.Request.URL.Path = "/test2"
		r.HandleContext(c)
	})
	r.GET("/test2", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"hello": "world"})
	})

}

//路由组
func group() {
	r := gin.Default()
	userGroup := r.Group("/user")
	{
		userGroup.GET("/index", func(c *gin.Context) {
			c.JSON(http.StatusOK, "get")
		})
		userGroup.GET("/login", func(c *gin.Context) {
			c.JSON(http.StatusOK, "get")
		})
		userGroup.POST("/login", func(c *gin.Context) {
			c.JSON(http.StatusOK, "post")
		})
		//支持路由组嵌套
		newUserGroup := userGroup.Group("/person")
		newUserGroup.GET("/name", func(context *gin.Context) {
			context.JSON(http.StatusOK, "ok")
		})

	}
	shopGroup := r.Group("/shop")
	{
		shopGroup.GET("/index", func(c *gin.Context) {
			c.JSON(http.StatusOK, "get")
		})
		shopGroup.GET("/cart", func(c *gin.Context) {
			c.JSON(http.StatusOK, "get")
		})
		shopGroup.POST("/checkout", func(c *gin.Context) {
			c.JSON(http.StatusOK, "post")
		})
	}
	r.Run(":9090")
}
func main() {
	//firstDemo()
	//buZhuanYi()
	//manyJson()
	//getParam()
	//getPost()
	//getJsonQuery()
	//pathQuery()
	//uploadfile()
	group()
}
